using System;
using System.Collections.Generic;
using System.Linq;
using GameFramework.Battle.Core;
using UnityEditor;
using UnityEditor.AnimatedValues;
using UnityEngine;
using Yoozoo.Gameplay.RTS;

namespace Gameplay.RTS.Editor
{
#if UNITY_EDITOR
    
    public class AttackActionEditorWindow : EditorWindow
    {
        private AnimBool fadeGroup;
        private AnimBool fadeGroup2;
        private Dictionary<int, AttackActionConfig> _actions = new Dictionary<int, AttackActionConfig>();
        private int addKey;
        private int num;
        
        private int addHeroKey;
        private Vector2 pos = new Vector2(0, 0);
        private List<int> waitDeleteKey = new List<int>();
        private List<Vector2Int> waitDeleteKeyAndIndex = new List<Vector2Int>();
        private List<int> waitAddKey = new List<int>();


        private List<Vector2Int> waitDeleteKeyAndIndex2 = new List<Vector2Int>();
        private List<int> waitAddKey2 = new List<int>();

        public AttackActionConfig[] subActions;
        private bool isInit = false;

        private Dictionary<int, SoldierAttackActionConfig> _attackListConfigs;

        private SoldierAttackActionConfigFather _attackFatherConfig;
        private Dictionary<int, bool> m_states = new Dictionary<int, bool>();
        private List<int> m_listActions = new List<int>(100);
        private int specialPercent;
        private int specialTimes;
        private void OnEnable()
        {
            fadeGroup = new AnimBool(false);
            // 注册动画监听
            fadeGroup.valueChanged.AddListener(Repaint);

            fadeGroup2 = new AnimBool(false);
            // 注册动画监听
            fadeGroup2.valueChanged.AddListener(Repaint);
        }

        private void OnDisable()
        {
            // 移除动画监听
            fadeGroup.valueChanged.RemoveListener(Repaint);
            fadeGroup2.valueChanged.RemoveListener(Repaint);
            isInit = false;
        }

        [MenuItem("GTATools/GamePlay/RTS/RTS普攻指令工具", false, 0)]
        private static void OpenParticleHelperWindow()
        {
            AttackActionEditorWindow win = GetWindow<AttackActionEditorWindow>("RTS普攻指令工具");
            win.Show();
        }

        private void LoadConfig()
        {
            _actions.Clear();
            ArmyManager armyManger = ArmyManager.Instance;
            RTSResourceManager resourceManager = armyManger.ResourceManager;
            RtsJsonConfigManager jsonManager = resourceManager.JsonManager;
            
            subActions = jsonManager.GetSubActionsInEditor();
            for (int i = 0; i < subActions.Length; i++)
            {
                var action = subActions[i];
                _actions.Add(action.actionID, action);
            }

            _attackListConfigs =
                ArmyManager.Instance.ResourceManager.JsonManager.GetSoldierAttackActionConfigInEditor();

            _attackFatherConfig = ArmyManager.Instance.ResourceManager.JsonManager.GetSoldierAttackActionConfigFather();
        }

        private void OnGUI()
        {
            if (!isInit)
            {
                isInit = true;
                LoadConfig();
            }
            
            if (ArmyManager.Instance != null)
            {
                if (GUILayout.Button("加载配置"))
                {
                    LoadConfig();
                }
                    
                if (GUILayout.Button("重载配置"))
                {
                    ArmyManager.Instance.ResourceManager.JsonManager.ReloadActionConfig(() =>
                    {
                        var marchDatas = ArmyManager.Instance.MarchManager.GetAllMarchEntities();
                        foreach (var marchData in marchDatas)
                        {
                            var square =  marchData.GetBattleSquare();
                            square.ReloadChildActionConfig();
                        }
                    });
                }
            }

            pos = EditorGUILayout.BeginScrollView(pos);
            fadeGroup.target = EditorGUILayout.Foldout(fadeGroup.target, "指令集", true);

            if (EditorGUILayout.BeginFadeGroup(fadeGroup.faded))
            {
                CreateActionButton();
                if (waitDeleteKeyAndIndex.Count > 0)
                {
                    List<AttackActionInfo> list = new List<AttackActionInfo>();
                    foreach (var key in waitDeleteKeyAndIndex)
                    {
                        var actions = _actions[key.x];

                        actions.actions[key.y] = null;
                        for (int i = 0; i < actions.actions.Length; i++)
                        {
                            if (actions.actions[i] != null)
                            {
                                list.Add(actions.actions[i]);
                            }
                        }

                        _actions[key.x].actions = list.ToArray();
                    }

                    waitDeleteKeyAndIndex.Clear();
                }

                if (waitAddKey.Count > 0)
                {
                    foreach (var key in waitAddKey)
                    {
                        var actions = _actions[key];
                        var targetLength = actions.actions.Length + 1;
                        var infos = new AttackActionInfo[targetLength];
                        for (int i = 0; i < actions.actions.Length; i++)
                        {
                            infos[i] = actions.actions[i];
                        }

                        for (int i = actions.actions.Length; i < infos.Length; i++)
                        {
                            infos[i] = new AttackActionInfo();
                        }

                        _actions[key].actions = infos;
                    }

                    waitAddKey.Clear();
                }

                if (waitDeleteKey.Count > 0)
                {
                    foreach (var deletekey in waitDeleteKey)
                    {
                        _actions.Remove(deletekey);
                    }

                    waitDeleteKey.Clear();
                }

                addKey = EditorGUILayout.IntField("actionId", addKey);
                num = EditorGUILayout.IntField("actionNum", num);
                if (GUILayout.Button("添加"))
                {
                    if (_actions.ContainsKey(addKey))
                    {
                        EditorUtility.DisplayDialog("提示", "键值重复了", "确认");
                    }
                    else
                    {
                        var infos = new AttackActionInfo[num];
                        var config = new AttackActionConfig();
                        config.actionID = addKey;
                        config.actions = infos;
                        for (int i = 0; i < infos.Length; i++)
                        {
                            infos[i] = new AttackActionInfo();
                        }

                        ;
                        _actions.Add(addKey, config);
                    }
                }

                if (GUILayout.Button("保存配置"))
                {
                    if (ArmyManager.Instance != null && ArmyManager.Instance.ResourceManager == null)
                    {
                        EditorUtility.DisplayDialog("提示", "请进入沙盘之后再点此按钮", "确认");
                    }
                    else
                    {
                        if (_actions.Count > 0)
                        {
                            ArmyManager.Instance.ResourceManager.JsonManager.SaveActionOffsetConfig(
                                _actions.Values.ToArray());
                            EditorUtility.DisplayDialog("提示", "保存成功", "确认");
                            AssetDatabase.Refresh();
                        }
                    }
                }
            }

            EditorGUILayout.EndFadeGroup();

            fadeGroup2.target = EditorGUILayout.Foldout(fadeGroup2.target, "兵种指令", true);

            if (EditorGUILayout.BeginFadeGroup(fadeGroup2.faded))
            {
                if (_attackListConfigs != null)
                {
                    var enumerator = _attackListConfigs.GetEnumerator();

                    while (enumerator.MoveNext())
                    {
                        EditorGUILayout.LabelField("soldierType", enumerator.Current.Key.ToString());
                        var value = enumerator.Current.Value;
                        
                       
                        EditorGUILayout.BeginVertical();
                        if (!m_states.ContainsKey(value.soldierType))
                        {
                            m_states.Add(value.soldierType,false);
                        }
                        value.useActionId = LayoutSoldierAction(value.useActionId,value.soldierType, "指令集列表");
                        //                        value.standActionIds = LayoutSoldierAction(value.standActionIds, value.soldierType, "站立指令集列表");
                        //                        value.squatActionIds = LayoutSoldierAction(value.squatActionIds, value.soldierType, "蹲下指令集列表");
                        //                        value.runActionIds = LayoutSoldierAction(value.runActionIds,value.soldierType, "跑动指令集列表");
                        value.specialPercent = EditorGUILayout.IntField("攻击出现特殊攻击概率", value.specialPercent);
                        value.specialTimes = EditorGUILayout.IntField("特殊攻击次数", value.specialTimes);
                        value.counterPercent = EditorGUILayout.IntField("反击概率", value.counterPercent);
                        EditorGUILayout.EndVertical();
                        EditorGUILayout.Space(2);
                        EditorGUILayout.Space();
                    }

                    //todo
                    if (waitDeleteKeyAndIndex2.Count > 0)
                    {
                        List<int> list = new List<int>();
                        foreach (var key in waitDeleteKeyAndIndex2)
                        {
                            var config = _attackListConfigs[key.x];

                            config.useActionId[key.y] = -1;
                            for (int i = 0; i < config.useActionId.Length; i++)
                            {
                                if (config.useActionId[i] != -1)
                                {
                                    list.Add(config.useActionId[i]);
                                }
                            }

                            _attackListConfigs[key.x].useActionId = list.ToArray();
                        }

                        waitDeleteKeyAndIndex2.Clear();
                    }

                    if (waitAddKey2.Count > 0)
                    {
                        foreach (var key in waitAddKey2)
                        {
                            var actions = _attackListConfigs[key];
                            var targetLength = actions.useActionId.Length + 1;
                            var infos = new int[targetLength];
                            for (int i = 0; i < actions.useActionId.Length; i++)
                            {
                                infos[i] = actions.useActionId[i];
                            }

                            for (int i = actions.useActionId.Length; i < infos.Length; i++)
                            {
                                infos[i] = 0;
                            }

                            _attackListConfigs[key].useActionId = infos;
                        }

                        waitAddKey2.Clear();
                    }

//todoend
                    enumerator.Dispose();


                    addHeroKey = EditorGUILayout.IntField("SoldierId", addHeroKey);
//                    num = EditorGUILayout.IntField("actionNum", num);
                    if (GUILayout.Button("添加"))
                    {
                        if (_attackListConfigs.ContainsKey(addHeroKey))
                        {
                            EditorUtility.DisplayDialog("提示", "键值重复了", "确认");
                        }
                        else
                        {
                            var config = new SoldierAttackActionConfig();
                            config.soldierType = addHeroKey;
                            config.useActionId = new int[]{0};
                            _attackListConfigs.Add(addHeroKey, config);
                        }
                    }
                    
                    GUILayout.Label("其他设置");
                    GUILayout.Space(10);

                    
                    
                    if (GUILayout.Button("保存兵种指令配置"))
                    {
                        if (ArmyManager.Instance != null && ArmyManager.Instance.ResourceManager == null)
                        {
                            EditorUtility.DisplayDialog("提示", "请进入沙盘之后再点此按钮", "确认");
                        }
                        else
                        {
                            if (_actions.Count > 0)
                            {
                                ArmyManager.Instance.ResourceManager.JsonManager.SaveSoldierAttackActionConfig();
                                EditorUtility.DisplayDialog("提示", "保存成功", "确认");
                                AssetDatabase.Refresh();
                            }
                        }
                    }
                }
            }


            EditorGUILayout.EndFadeGroup();

            EditorGUILayout.EndScrollView();
        }

        private void CreateActionButton()
        {
            var enmerator = _actions.GetEnumerator();

            while (enmerator.MoveNext())
            {
                var key = enmerator.Current.Key;
                var attackActionConfig = enmerator.Current.Value;

                EditorGUILayout.LabelField("actionid", key.ToString());

                for (int i = 0; i < attackActionConfig.actions.Length; i++)
                {
                    EditorGUILayout.BeginHorizontal();
                    var action = attackActionConfig.actions[i];
                    if (action == null)
                    {
                        continue;
                    }

                    var type = action.GetType();
                    bool showAnimType = true;
                    foreach (var propertyInfo in type.GetProperties())
                    {
                        var name = propertyInfo.Name;
                        var value = propertyInfo.GetValue(action);
                        var protertyType = value?.GetType() ?? typeof(object);

                        if (protertyType == typeof(Single))
                        {
                            var result = EditorGUILayout.FloatField(name, (float) value,GUILayout.MaxWidth(300));
                            propertyInfo.SetValue(action, result);
                        }
                        else if (protertyType == typeof(SubActionType))
                        {
                            if ((SubActionType) value == SubActionType.Attack)
                            {
                                showAnimType = false;
                            }
                            var result = EditorGUILayout.EnumPopup(name, (SubActionType) value,GUILayout.MaxWidth(300));
                            propertyInfo.SetValue(action, result);
                        }
                        else if (protertyType == typeof(EAnimationType))
                        {
                            if (showAnimType)
                            {
                                var result = EditorGUILayout.EnumPopup(name, (EAnimationType) value, GUILayout.Width(300));
                                propertyInfo.SetValue(action, result);
                            }
                        }
                        else if (protertyType == typeof(Int32))
                        {
                            var result = EditorGUILayout.IntField(name, (int) value,GUILayout.MaxWidth(300));
                            propertyInfo.SetValue(action, result);
                        }
                        else if (protertyType == typeof(bool))
                        {
                            var result = EditorGUILayout.Toggle(name, (bool) value,GUILayout.MaxWidth(300));
                            propertyInfo.SetValue(action, result);
                        }
                    }

                    EditorGUILayout.Space();

                    if (GUILayout.Button("删除指令",GUILayout.MaxWidth(300)))
                    {
                        waitDeleteKeyAndIndex.Add(new Vector2Int(key, i));
                    }

                    EditorGUILayout.EndHorizontal();
                }

                if (GUILayout.Button("添加指令"))
                {
                    waitAddKey.Add(key);
                }


                if (GUILayout.Button("删除该键"))
                {
                    waitDeleteKey.Add(key);
                }

                EditorGUILayout.Space();
            }

            enmerator.Dispose();
        }

        private int[] LayoutSoldierAction(int[] actionIds, int type, string name)
        {
            if (m_states.TryGetValue(type,out bool state))
            {
                
            }
            else
            {
                state = false;
            }
            state = EditorGUILayout.Foldout(state, name);
            m_states[type] = state;
            if (state == false) return actionIds;
            
            if (actionIds == null)
            {
                actionIds = new int[] { };
            }
            
            m_listActions.AddRange(actionIds);
            
            for (int i = 0; i < m_listActions.Count; i++)
            {
                EditorGUILayout.BeginHorizontal();
                m_listActions[i] = EditorGUILayout.IntField("ID：", m_listActions[i]);
                if (GUILayout.Button("删除此ID",GUILayout.MaxWidth(100f)))
                {
                    m_listActions.RemoveAt(i);
                    i--;
                }

                EditorGUILayout.EndHorizontal();
                EditorGUILayout.Space();
            }

            if (GUILayout.Button("添加ID",GUILayout.MaxWidth(100f)))
            {
                m_listActions.Add(0);
            }


            if (m_listActions.Count == actionIds.Length)
            {
                for (int i = 0; i < actionIds.Length; ++i)
                {
                    actionIds[i] = m_listActions[i];
                }
            }
            else
            {
                actionIds = m_listActions.ToArray();
            }
            m_listActions.Clear();

            return actionIds;
        }
        
    }
#endif
}